package com.pengshun.modules.api.user.service.impl;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSONObject;
import com.pengshun.modules.api.mapper.SystemMapper;
import com.pengshun.modules.api.user.repository.UserBankRepository;
import com.pengshun.modules.api.user.service.UserBankService;
import com.pengshun.modules.api.user.service.dto.UserBankDto;
import com.pengshun.modules.api.user.service.mapstruct.UserBankTodo;
import com.pengshun.modules.common.BankTools;
import com.pengshun.modules.common.BaseResult;
import com.pengshun.modules.domain.SystemBank;
import com.pengshun.modules.domain.UserBank;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.swing.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.*;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class UserBankServiceImpl implements UserBankService {

    private final UserBankRepository userBankRepository;
    private final UserBankTodo userBankTodo;
    private final SystemMapper systemMapper;

    @Override
    public BaseResult bankList(Long id) {
        List<UserBank> list = userBankRepository.findByStatusAndUserId(1, id);
        for (UserBank bank : list) {
            bank.setBankCardNo(bank.getBankCardNo().substring(bank.getBankCardNo().length() - 4, bank.getBankCardNo().length()));
        }
        return new BaseResult(0, list);
    }

    @Override
    public BaseResult save(UserBankDto para) {
        UserBank userBank = userBankRepository.findByBankCardNoAndUserId(para.getBankCardNo(), para.getUserId());
        if (userBank != null) {
            if (userBank.getStatus() == 1) {
                return new BaseResult(1, "不能重复添加银行卡");
            }
            if (userBank.getStatus() == 2) {
                userBank.setStatus(1);
                userBankRepository.save(userBank);
                return new BaseResult(0, "添加成功");
            }
        }

        String res = BankTools.getCardDetail(para.getBankCardNo());
        JSONObject jsons = JSONObject.parseObject(res);
        boolean validated = (boolean) jsons.get("validated");
        if (!validated) {
            return new BaseResult(1, "卡号错误！请检查后重试");
        }
        String code = jsons.get("bank").toString();

        SystemBank bank = systemMapper.findSystemBankByCode(code);
        if (bank == null) {
            return new BaseResult(1, "暂时不支持该银行");
        }
        if ("1".equals(para.getIsSelf())) {
            String host = "https://bcard3and4.market.alicloudapi.com";
            String path = "/bank3CheckNew";
            String appcode = "502b989e2d704cc3b153bfc164ad8090";
            try {
                String urlSend = host + path + "?idCard=" + para.getIdcard() + "&name=" + URLEncoder.encode(para.getUserName(), "UTF-8") + "&accountNo=" + para.getBankCardNo();  // 【5】拼接请求链接
                URL url = new URL(urlSend);
                HttpURLConnection httpURLCon = (HttpURLConnection) url.openConnection();
                httpURLCon.setRequestProperty("Authorization", "APPCODE " + appcode);
                int httpCode = httpURLCon.getResponseCode();
                if (httpCode == 200) {
                    String json = read(httpURLCon.getInputStream());
                    JSONObject jsonObject1 = JSONObject.parseObject(json);
                    String status = jsonObject1.get("status").toString();
                    String msg = jsonObject1.get("msg").toString();
                    if (status.equals("01")) {
                        para.setTypeName(jsonObject1.get("cardType").toString());
                        para.setBankName(bank.getBankName());
                        para.setCreateTime(new DateTime());
                        para.setBankSmallIcon(bank.getBankSmallIcon());
                        para.setBankBigIcon(bank.getBankBigIcon());
                        para.setBackColor(bank.getBackColor());
                        para.setStatus(1);
                        userBankRepository.save(userBankTodo.toEntity(para));
                        return new BaseResult(0, "添加成功");
                    } else {
                        return new BaseResult(1, msg);
                    }
                } else {
                    Map<String, List<String>> map = httpURLCon.getHeaderFields();
                    String error = map.get("X-Ca-Error-Message").get(0);
                    if (httpCode == 400 && error.equals("Invalid AppCode `not exists`")) {
                        return new BaseResult(1, "AppCode错误");
                    } else if (httpCode == 400 && error.equals("Invalid Url")) {
                        return new BaseResult(1, "请求的 Method、Path 或者环境错误");
                    } else if (httpCode == 400 && error.equals("Invalid Param Location")) {
                        return new BaseResult(1, "参数错误");
                    } else if (httpCode == 403 && error.equals("Unauthorized")) {
                        return new BaseResult(1, "服务未被授权（或URL和Path不正确");
                    } else if (httpCode == 403 && error.equals("Quota Exhausted")) {
                        return new BaseResult(1, "套餐包次数用完");
                    } else {
                        return new BaseResult(1, "参数名错误 或 其他错误");
                    }
                }

            } catch (MalformedURLException e) {
                System.out.println("");
                return new BaseResult(1, "URL格式错误");
            } catch (UnknownHostException e) {
                return new BaseResult(1, " URL地址错误");
            } catch (Exception e) {
                // 打开注释查看详细报错异常信息
                return new BaseResult(1, e.getMessage());
            }
        }else{
            para.setTypeName("借记卡");
            para.setBankName(bank.getBankName());
            para.setCreateTime(new DateTime());
            para.setBankSmallIcon(bank.getBankSmallIcon());
            para.setBankBigIcon(bank.getBankBigIcon());
            para.setBackColor(bank.getBackColor());
            para.setStatus(1);
            userBankRepository.save(userBankTodo.toEntity(para));
            return new BaseResult(0, "添加成功");
        }
    }

    /*
     * 读取返回结果
     */
    private static String read(InputStream is) throws IOException {
        StringBuffer sb = new StringBuffer();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        while ((line = br.readLine()) != null) {
            line = new String(line.getBytes(), "utf-8");
            sb.append(line);
        }
        br.close();
        return sb.toString();
    }

    @Override
    public BaseResult update(UserBankDto para) {
        UserBank userBank = userBankRepository.findById(para.getUserBankId()).orElseGet(UserBank::new);
        userBank.setStatus(2);
        userBankRepository.save(userBank);
        return new BaseResult(0);
    }

    @Override
    public BaseResult list() {
        List<SystemBank> list = systemMapper.systemBanKList();
        return new BaseResult(0, list);
    }

    @Override
    public BaseResult bank(String bankCardNo) {
        String name = BankTools.getCardDetail(bankCardNo);
        SystemBank bank = systemMapper.findSystemBankByCode(name);
        if (bank == null) {
            return new BaseResult(1, "暂不支持该银行");
        }
        return new BaseResult(0, bank);

    }

}
